<template>
  <div class="d-flex">
    <div
      v-loading="loading"
      style="min-height: 353px; position: relative"
      :class="typeIndex > -1 && 'border-right'"
    >
      <el-scrollbar
        v-if="bankType.length"
        tag="ul"
        wrap-class="c-area-dropdown__wrap"
        view-class="el-select-dropdown__list"
        ref="scrollbar"
      >
        <li v-if="bankType.length" class="el-cascader-node">
          <el-checkbox
            :indeterminate="typeAllIndeterminate"
            v-model="typeAllChecked"
            @change="handleAllChecked"
          >
            <div class="bp-label pl-1">全选</div>
          </el-checkbox>
        </li>
        <li
          v-for="(type, index) in bankType"
          :key="type.enum_key"
          class="el-cascader-node bp-node"
          :class="{ 'is-active': type.checked, 'in-checked-path': typeIndex === index }"
          @click.stop="handleTypeClick(type, index)"
        >
          <el-checkbox
            v-model="type.checked"
            @click.native.stop
            @change="handleTypeChecked(type, index)"
          ></el-checkbox>
          <span
            class="bp-label"
            :class="{ 'text-primary font-weight-bold': type.indeterminate }"
            :title="type.enum_value"
          >
            {{ type.enum_value }}
          </span>
          <template>
            <i v-if="type.loading" class="el-icon-loading el-cascader-node__postfix"></i>
            <i v-else class="el-icon-arrow-right el-cascader-node__postfix"></i>
          </template>
        </li>
      </el-scrollbar>
      <div v-else-if="!loading" class="bp__empty-text">{{ noDataText || '暂无数据' }}</div>
    </div>

    <div v-if="typeIndex > -1" class="bank-panel">
      <div class="bp-query" v-if="showAddressSelector">
        <div
          class="bp-query-item"
          :class="{
            'is-active': showType === 'address' || queryAddress,
            'text-muted': !queryAddressLabel,
          }"
          @click.stop="handleSelectAddress"
        >
          <div class="bp-query-label">{{ queryAddressLabel || '所属地区' }}</div>
          <div class="el-icon-arrow-down"></div>
        </div>
      </div>

      <div style="position: relative">
        <el-scrollbar
          v-if="banks.length"
          tag="ul"
          :wrap-class="showAddressSelector ? 'c-query-dropdown__wrap' : 'c-area-dropdown__wrap'"
          view-class="el-select-dropdown__list"
          ref="scrollbarSecond"
        >
          <li
            v-for="(bank, index) in banks"
            :key="index"
            class="el-cascader-node"
            :class="{ 'is-active': bank.checked }"
            @click.stop
          >
            <el-checkbox
              :indeterminate="bank.indeterminate"
              v-model="bank.checked"
              @change="handleBankChecked(bank, index)"
            >
              <div class="bp-label" :title="bank.agency_name">{{ bank.agency_name }}</div>
            </el-checkbox>
          </li>
        </el-scrollbar>
        <div v-else-if="!loading" class="bp__empty-text">{{ noDataText || '暂无数据' }}</div>

        <transition name="el-fade-in">
          <div v-show="showType !== 'bank'" class="bp__mask"></div>
        </transition>

        <transition name="el-fade-in">
          <select-org-bank-address
            v-show="showType === 'address'"
            v-model="queryAddress"
            position="center"
            class="bp-query-wrap"
            wrap-class="c-query-inner-dropdown__wrap"
            @close="handleQueryClose"
            @change="handleQueryAddressChange"
          ></select-org-bank-address>
        </transition>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import SelectOrgBankAddress from '@/gov/components/select/selectOrgBank/PanelAddress'

export default {
  components: {
    SelectOrgBankAddress,
  },
  props: {
    value: String,
    disabled: Boolean,
    noDataText: String,
    productId: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      loading: false,
      bankType: [],
      typeIndex: -1,
      typeAllIndeterminate: false,
      typeAllChecked: false,
      bankIndex: -1,
      banks: [],

      // 地址选择
      showType: 'bank',
      queryAddress: '',
      queryAddressLabel: '',
    }
  },
  computed: {
    ...mapGetters(['user']),
    showAddressSelector() {
      return this.user.orgRegionLever < 3
    },
  },
  watch: {
    productId() {
      this.getBankType()
    },
  },
  created() {
    this.getBankType()
  },
  mounted() {},
  methods: {
    getBankType() {
      this.loading = true
      const tableName = this.productId ? 'industrial_package_agency_view' : 'system_enum'
      const params = this.productId
        ? {
            'industrial_package_id.eq': this.productId,
            groupFields: 'agency_type_sub',
            fields: ['agency_type_sub', 'agency_type_sub_name'],
          }
        : {
            'enum_field.eq': 'credit_agency_info.agency_type_sub',
            fields: ['enum_value', 'enum_key'],
          }
      this.$api
        .getData({
          table: tableName,
          params,
        })
        .then(res => {
          let list = res.data || []
          if (this.productId) {
            list = list
              .filter(item => item.agency_type_sub)
              .map(item => {
                return {
                  enum_value: item.agency_type_sub_name,
                  enum_key: item.agency_type_sub,
                }
              })
          }
          this.bankType = list.map(it => ({
            ...it,
            indeterminate: false,
            checked: false,
            loading: false,
            children: [],
            hasFetch: false,
          }))
        })
        .finally(() => {
          this.loading = false
        })
    },
    getBankByType(row, index) {
      row.loading = true
      row.hasFetch = true
      const table = this.productId ? 'industrial_package_agency_view' : 'credit_agency_info_view'
      const params = this.productId
        ? {
            'industrial_package_id.eq': this.productId,
            'agency_type_sub.eq': row.enum_key,
            address_code: this.queryAddress || this.user.queryAddressCode,
            groupFields: 'agency_id',
            fields: ['agency_id', 'agency_name', 'address_code', 'agency_type_sub'],
          }
        : {
            'agency_type.eq': 1,
            'agency_type_sub.eq': row.enum_key,
            address_code: this.queryAddress || this.user.queryAddressCode,
            fields: [
              'agency_id',
              'agency_name',
              'address_code',
              'address',
              'address_detail',
              'agency_type',
              'agency_type_sub',
              'org_region_lever',
            ],
          }
      this.$api
        .getData({
          table,
          params,
        })
        .then(res => {
          row.children = (res.data || []).map(it => ({
            ...it,
            indeterminate: false,
            checked: row.checked,
          }))
          if (this.typeIndex === index) {
            this.banks = row.children
          }
        })
        .finally(() => {
          row.loading = false
        })
    },
    handleAllChecked(val = true) {
      this.changeAll(val)
      this.$emit('change', {
        type: 'all',
        value: val,
      })
    },
    handleTypeChecked(row, index) {
      row.indeterminate = false
      this.changeType(row, index)
      this.refreshChildren(row)
      this.emitChange('type')
    },
    handleTypeClick(row, index) {
      this.typeIndex = index
      this.bankIndex = -1
      if (row.hasFetch) {
        this.banks = row.children || []
      } else {
        this.getBankByType(row, index)
      }
    },
    handleBankChecked(row, _) {
      if (this.typeIndex > -1) {
        const type = this.bankType[this.typeIndex]
        type.indeterminate = this.isIndeterminate(type.children)
        const firstNextChecked = row.checked && !type.indeterminate
        if (type.checked !== firstNextChecked) {
          type.checked = firstNextChecked
          this.changeType(type, this.typeIndex)
        }
      }
      this.emitChange('bank')
    },
    changeAll(val) {
      this.typeIndex = -1
      this.typeAllIndeterminate = false
      for (const type of this.bankType) {
        type.indeterminate = false
        type.checked = val
        const { children = [] } = type
        for (const child of children) {
          child.indeterminate = false
          child.checked = val
        }
      }
    },
    changeType(row, index) {
      this.typeAllIndeterminate = this.isIndeterminate(this.bankType)
      this.typeAllChecked = !this.typeAllIndeterminate && row.checked
      this.handleTypeClick(row, index)
    },
    emitChange(type) {
      this.$emit('change', {
        type,
        types: this.bankType.filter(it => it.checked),
        banks: this.getCheckedList(),
      })
    },
    refreshChildren(row) {
      if (!row.children) return
      for (const child of row.children) {
        child.checked = row.checked
      }
    },
    isIndeterminate(data) {
      const { length } = data
      if (!length) return false
      for (let i = 1; i < length; i++) {
        if (data[i - 1].checked !== data[i].checked) {
          return true
        }
      }
      return false
    },
    handleSelectAddress() {
      this.showType = this.showType === 'address' ? 'bank' : 'address'
    },
    handleQueryClose() {
      this.showType = 'bank'
    },
    handleQueryAddressChange(val) {
      this.queryAddressLabel = val.geoName || ''
      if (this.typeIndex > -1) {
        this.getBankByType(this.bankType[this.typeIndex], this.typeIndex)
      }
    },
    getCheckedList() {
      const res = []
      for (const type of this.bankType) {
        if (type.checked || !type.children) continue
        for (const bank of type.children) {
          if (bank.checked) {
            res.push(bank)
          }
        }
      }
      return res
    },
    clear() {
      this.typeIndex = -1
      this.typeAllIndeterminate = false
      this.typeAllChecked = false
      this.bankIndex = -1
      this.showType = 'bank'
      this.queryAddress = ''
      this.queryAddressLabel = ''
      this.resetSelected()
    },
    resetQuery() {
      this.showType = 'bank'
    },
    resetSelected() {
      for (const type of this.bankType) {
        type.checked = false
        type.indeterminate = false
        if (!type.children) continue
        for (const bank of type.children) {
          bank.checked = false
          bank.indeterminate = false
        }
      }
    },
  },
}
</script>

<style lang="scss" scoped>
.el-cascader-node /deep/ .el-checkbox__label {
  line-height: 14px;
  vertical-align: middle;
}
.bp__empty-text {
  padding: 145px 0;
  color: $gray-600;
  min-width: 200px;
  text-align: center;
}
.bp-node {
  height: auto;
  min-height: 34px;
  line-height: 1rem;
}
.in-checked-path {
  color: $primary;
}
.bp-label {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 155px;
}

.bank-panel {
  position: relative;
}

.bp__mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
  z-index: 2000;
}

.bp-query-wrap {
  top: 0;
  height: 310px;
}

.bp-query {
  min-width: 260px;
  display: flex;
  border-bottom: 1px solid $gray-200;
  height: 44px;

  &-item {
    flex: 1;
    width: 50%;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
    text-align: center;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: color 0.3s;

    &:hover,
    &.is-active {
      color: $primary !important;
      color: var(--primary) !important;
    }
  }

  &-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
</style>
